package com.youdianstar.app.util

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import com.youdianstar.app.common.util.LogUtil
import com.youdianstar.app.support.ApiRepository
import com.youdianstar.app.common.event.NetStateLiveData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import android.os.Handler
import android.os.Looper
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.util.*

/**
 * ZaloPay支付工具类
 * 基于后端API实现真实的ZaloPay支付流程
 */
object ZaloPayUtil : KoinComponent {

    private const val TAG = "ZaloPayUtil"
    private val apiRepository: ApiRepository by inject()

    // ZaloPay支付结果码
    const val ZALOPAY_RESULT_SUCCESS = 1
    const val ZALOPAY_RESULT_FAILED = -1
    const val ZALOPAY_RESULT_CANCELLED = 4

    // 存储支付回调的Map，用于处理支付结果
    private val paymentCallbacks = mutableMapOf<String, (result: Int, message: String?) -> Unit>()

    /**
     * 启动ZaloPay支付 - 基于后端API实现
     * @param activity 当前Activity
     * @param deviceId 设备ID（可选）
     * @param powerBankType 充电宝类型
     * @param onPaymentUrlReady 支付URL准备好时的回调（可选，用于提取orderUuid等）
     * @param callback 支付结果回调
     */
    fun startPayment(
        activity: Activity,
        deviceId: String? = null,
        powerBankType: Int = 0,
        onPaymentUrlReady: ((Any?) -> Unit)? = null,
        callback: (Any, Any?) -> Unit
    ) {
        try {
            LogUtil.d(TAG, "开始创建ZaloPay订单，deviceId: $deviceId, powerBankType: $powerBankType")
            
            // 调用后端API获取ZaloPay支付信息
            createZaloPayOrder(activity, deviceId, powerBankType) { paymentUrl ->
                LogUtil.d(TAG, "createZaloPayOrder回调执行: paymentUrl=$paymentUrl, onPaymentUrlReady=${onPaymentUrlReady != null}")
                
                if (paymentUrl != null) {
                    LogUtil.d(TAG, "ZaloPay订单创建成功，支付URL: $paymentUrl")
                    
                    // 通知支付URL已准备好（在启动支付之前，让调用方有机会提取orderUuid）
                    LogUtil.d(TAG, "准备调用onPaymentUrlReady回调")
                    onPaymentUrlReady?.invoke(paymentUrl)
                    LogUtil.d(TAG, "onPaymentUrlReady回调已执行")
                    
                    // 优先尝试启动ZaloPay应用
                    if (isZaloPayAppInstalled(activity)) {
                        LogUtil.d(TAG, "检测到ZaloPay应用已安装，启动原生支付")
                        launchZaloPayApp(activity, paymentUrl) { result, msg ->
                            callback(result, msg)
                        }
                    } else {
                        LogUtil.d(TAG, "ZaloPay应用未安装，使用H5支付")
                        // 如果没有安装应用，使用H5支付
                        launchZaloPayWeb(activity, paymentUrl) { result, msg ->
                            callback(result, msg)
                        }
                    }
                } else {
                    LogUtil.e(TAG, "ZaloPay订单创建失败，paymentUrl为null")
                    // 确保回调在主线程执行
                    Handler(Looper.getMainLooper()).post {
                        callback(ZALOPAY_RESULT_FAILED, "创建ZaloPay订单失败")
                    }
                }
            }

        } catch (e: Exception) {
            LogUtil.e("ZaloPay支付启动失败", e)
            // 确保回调在主线程执行
            Handler(Looper.getMainLooper()).post {
                callback(ZALOPAY_RESULT_FAILED, "支付启动失败: ${e.message}")
            }
        }
    }

    /**
     * 创建ZaloPay订单 - 调用后端API
     */
    private fun createZaloPayOrder(
        context: Context,
        deviceId: String?,
        powerBankType: Int,
        callback: (paymentUrl: String?) -> Unit
    ) {
        val stateLiveData = NetStateLiveData<String>()
        val mainHandler = Handler(Looper.getMainLooper())
        
        // 在主线程注册观察者
        CoroutineScope(Dispatchers.Main).launch {
            stateLiveData.observeForever { response ->
                LogUtil.d(TAG, "收到订单创建响应: code=${response.code}, isSuccess=${response.isSuccess}, data=${response.data}, message=${response.message}")
                if (response.isSuccess) {
                    LogUtil.d(TAG, "ZaloPay订单创建成功，支付URL: ${response.data}")
                    // 回调在主线程执行
                    callback(response.data)
                } else {
                    LogUtil.e(TAG, "创建ZaloPay订单失败: code=${response.code}, message=${response.message}")
                    // 回调在主线程执行
                    callback(null)
                }
            }
        }

        // 在IO线程调用API
        CoroutineScope(Dispatchers.IO).launch {
            try {
                apiRepository.createZaloPayOrder(deviceId, powerBankType, stateLiveData)
            } catch (e: Exception) {
                LogUtil.e("创建ZaloPay订单异常", e)
                // 切换到主线程执行回调
                mainHandler.post {
                    callback(null)
                }
            }
        }
    }

    /**
     * 检查ZaloPay应用是否已安装
     */
    private fun isZaloPayAppInstalled(activity: Activity): Boolean {
        return try {
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse("zalopay://app"))
            intent.resolveActivity(activity.packageManager) != null
        } catch (e: Exception) {
            LogUtil.e("检查ZaloPay应用安装状态失败", e)
            false
        }
    }

    /**
     * 启动ZaloPay应用
     */
    private fun launchZaloPayApp(
        activity: Activity,
        paymentUrl: String,
        callback: (Any, Any?) -> Unit
    ) {
        try {
            // 生成唯一的支付ID用于回调识别
            val paymentId = generatePaymentId()
            paymentCallbacks[paymentId] = { result: Int, message: String? ->
                callback(result, message)
            }

            // 构建ZaloPay应用支付URL
            val appPaymentUrl = "zalopay://app/pay?url=${Uri.encode(paymentUrl)}&paymentId=$paymentId"
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(appPaymentUrl))
            
            activity.startActivity(intent)
            
            LogUtil.d(TAG, "已启动ZaloPay应用支付")

        } catch (e: Exception) {
            LogUtil.e("启动ZaloPay应用失败", e)
            // 确保回调在主线程执行
            Handler(Looper.getMainLooper()).post {
                callback(ZALOPAY_RESULT_FAILED, "启动支付失败: ${e.message}")
            }
        }
    }

    /**
     * 启动ZaloPay H5支付（备用方案）
     */
    private fun launchZaloPayWeb(
        activity: Activity,
        paymentUrl: String,
        callback: (Any, Any?) -> Unit
    ) {
        try {
            // 生成唯一的支付ID用于回调识别
            val paymentId = generatePaymentId()
            paymentCallbacks[paymentId] = { result: Int, message: String? ->
                callback(result, message)
            }

            // 使用浏览器打开支付页面
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(paymentUrl))
            activity.startActivity(intent)
            
            LogUtil.d(TAG, "已启动ZaloPay H5支付")
            
            // H5支付需要轮询检查订单状态
            setupH5PaymentResultListener(paymentId) { result, message ->
                callback(result, message)
            }

        } catch (e: Exception) {
            LogUtil.e("启动ZaloPay H5支付失败", e)
            // 确保回调在主线程执行
            Handler(Looper.getMainLooper()).post {
                callback(ZALOPAY_RESULT_FAILED, "启动H5支付失败: ${e.message}")
            }
        }
    }

    /**
* 设置H5支付结果监听 - 基于后端API轮询
     */
    private fun setupH5PaymentResultListener(
        paymentId: String,
        callback: (Any, Any?) -> Unit
    ) {
        // 这里可以实现订单状态轮询
        // 由于H5支付完成后会跳转回App，可以通过URL参数获取支付结果
        // 或者通过定时轮询后端API检查支付状态
        
        LogUtil.d(TAG, "设置H5支付结果监听，paymentId: $paymentId")
        
        // TODO: 实现订单状态轮询逻辑
        // 参考H5的checkPay方法，定时调用 /security/pay/check 接口
    }

    /**
     * 生成唯一的支付ID
     */
    private fun generatePaymentId(): String {
        return "zalo_pay_${System.currentTimeMillis()}_${Random().nextInt(10000)}"
    }

    /**
     * 处理ZaloPay支付结果回调
     * 这个方法会被Activity的onActivityResult调用
     */
    fun handlePaymentResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?,
        callback: (success: Boolean, message: String?) -> Unit
    ) {
        LogUtil.d(TAG, "处理ZaloPay支付结果，requestCode: $requestCode, resultCode: $resultCode")
        
        when (resultCode) {
            ZALOPAY_RESULT_SUCCESS -> {
                LogUtil.d(TAG, "ZaloPay支付成功")
                callback(true, "支付成功")
            }
            ZALOPAY_RESULT_CANCELLED -> {
                LogUtil.d(TAG, "ZaloPay支付取消")
                callback(false, "支付已取消")
            }
            ZALOPAY_RESULT_FAILED -> {
                LogUtil.d(TAG, "ZaloPay支付失败")
                callback(false, "支付失败")
            }
            else -> {
                LogUtil.d(TAG, "ZaloPay支付未知结果: $resultCode")
                callback(false, "支付结果未知")
            }
        }
    }

    /**
     * 检查支付状态 - 调用后端API
     * @param orderUuid 订单UUID
     * @param callback 检查结果回调
     */
    fun checkPaymentStatus(
        orderUuid: String,
        callback: (success: Boolean, message: String?) -> Unit
    ) {
        val stateLiveData = NetStateLiveData<Any>()
        val mainHandler = Handler(Looper.getMainLooper())
        
        // 在主线程注册观察者
        CoroutineScope(Dispatchers.Main).launch {
            stateLiveData.observeForever { response ->
                if (response.isSuccess) {
                    LogUtil.d(TAG, "支付状态检查成功: ${response.data}")
                    // 回调在主线程执行
                    callback(true, "支付成功")
                } else {
                    LogUtil.e("支付状态检查失败: ${response.message}")
                    // 回调在主线程执行
                    callback(false, response.message)
                }
            }
        }

        // 在IO线程调用API
        CoroutineScope(Dispatchers.IO).launch {
            try {
                apiRepository.checkPaymentStatus(orderUuid, stateLiveData)
            } catch (e: Exception) {
                LogUtil.e("检查支付状态异常", e)
                // 切换到主线程执行回调
                mainHandler.post {
                    callback(false, "检查支付状态失败: ${e.message}")
                }
            }
        }
    }

    /**
     * 清理支付回调
     */
    fun clearPaymentCallback(paymentId: String) {
        paymentCallbacks.remove(paymentId)
    }

    /**
     * 清理所有支付回调
     */
    fun clearAllPaymentCallbacks() {
        paymentCallbacks.clear()
    }
}